/*! @file conversion_benchmark.cu
 *        @brief Benchmark routines that convert CSR to all other matrix formats on CPU and GPU 
*/

/** @fn  csr_to_csr_conversion()
 *     @brief  Convert csr matrix from host to csr matrix on device
*/  
void csr_to_csr_conversion()
{
	int counter=0;
	timer tcsr;
	/*Create CSR matrix on device i.e. GPU*/
	cusp::csr_matrix<int, float, cusp::device_memory> A_CSR;
	/*Start CUDA Timer implemented using CUDAEvents */
	tcsr.start_timer();
	/*Perform Conversion CONVERSION_COUNTS times */
	for (counter=0; counter < CONVERSION_COUNTS; counter++)
	{
		A_CSR =  A_Host;
	}
	/*Wait for all threads to finish*/
	cudaThreadSynchronize();
	
	/*Print elapsed time in conversion process */
	double elapsed_time = tcsr.seconds_elapsed();
	printf("\n TIME FOR CSR TO CSR(DEVICE) : %lf Sec/Conversion \n " ,elapsed_time/CONVERSION_COUNTS);
}



/** @fn  csr_to_hyb_conversion()
 *     @brief  Convert csr matrix from host to hyb matrix on device
*/  
void csr_to_hyb_conversion()
{
	int counter=0;
	timer thyb;

	cusp::hyb_matrix<int, float, cusp::device_memory> A_HYB;

	thyb.start_timer();

	for (counter=0; counter < CONVERSION_COUNTS; counter++)
	{
		A_HYB =  A_Host;
	}
	cudaThreadSynchronize();

	double elapsed_time = thyb.seconds_elapsed();
	printf("\n TIME FOR CSR TO HYBRID : %lf Sec/Conversion \n " ,elapsed_time/CONVERSION_COUNTS);
}

/** @fn  csr_to_dia_conversion()
 *     @brief  Convert csr matrix from host to dia matrix on device
*/  
void csr_to_dia_conversion()
{
	int counter=0;
	timer tdia;

	cusp::dia_matrix<int, float, cusp::device_memory> A_DIA;

	tdia.start_timer();

	for (counter=0; counter < CONVERSION_COUNTS; counter++)
	{
		A_DIA =  A_Host;
	}
	cudaThreadSynchronize();

	double elapsed_time = tdia.seconds_elapsed();
	printf("\n TIME FOR CSR TO DIA : %lf Sec/Conversion \n " ,elapsed_time/CONVERSION_COUNTS);
}

/** @fn  csr_to_ell_conversion()
 *     @brief  Convert csr matrix from host to ell matrix on device
*/  
void csr_to_ell_conversion()
{
	int counter=0;
	timer tell;

	cusp::ell_matrix<int, float, cusp::device_memory> A_ELL;

	tell.start_timer();

	for (counter=0; counter < CONVERSION_COUNTS; counter++)
	{
		A_ELL =  A_Host;
	}
	cudaThreadSynchronize();

	double elapsed_time = tell.seconds_elapsed();
	printf("\n TIME FOR CSR TO ELL : %lf Sec/Conversion \n " ,elapsed_time/CONVERSION_COUNTS);
}

/** @fn  csr_to_coo_conversion()
 *     @brief  Convert csr matrix from host to coo matrix on device
*/  
void csr_to_coo_conversion()
{
	int counter=0;
	timer tcoo;

	cusp::coo_matrix<int, float, cusp::device_memory> A_COO;

	tcoo.start_timer();

	for (counter=0; counter < CONVERSION_COUNTS; counter++)
	{
		A_COO =  A_Host;
	}
	cudaThreadSynchronize();

	double elapsed_time = tcoo.seconds_elapsed();
	printf("\n TIME FOR CSR TO COO : %lf Sec/Conversion \n " ,elapsed_time/CONVERSION_COUNTS);

}


/** @fn  csr_to_coo_conversion()
 *     @brief  Call individual benchmarking routines
*/  
void matrix_conversion_benchmark()
{
	/*call individual conversion routines*/
	try
	{
		csr_to_csr_conversion();
		csr_to_coo_conversion();
		csr_to_hyb_conversion();
		csr_to_ell_conversion();
		csr_to_dia_conversion();
	}
	catch (char *exc)
	{
		printf("\n Exception in Conversion Benchmark : %s", exc);
	}
}
